package com.base.themvx.utils;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.widget.ImageView;

import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.annotation.RawRes;
import androidx.annotation.WorkerThread;
import androidx.core.content.res.ResourcesCompat;

import com.base.themvx.AppLog;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * ******************(^_^)***********************
 * User: 11776610771@qq.com
 * Date: 2017/4/25
 * Time: 16:31
 * DESC: 使用Picasso来加载图片
 * ******************(^_^)***********************
 */

public class ImageUtil {
    //    public static void loadImage(Context context, String picUrl, int newWidth, int newHeight, Drawable holderDrawable,
//                                 Drawable errorDrawable, ImageView targetIv
//            , Callback callback) {
//        RequestCreator loadRequest = loadImageRequest(context, picUrl,null,0);
//
//        if (newWidth > 0 && newHeight > 0) {
//            loadRequest.resize(newWidth, newHeight);
//            loadRequest.centerCrop();
//        }
//        else{
////            loadRequest.fit();
//        }
//        if (holderDrawable != null) {
//            loadRequest.placeholder(holderDrawable);
//        }
//        else{
//            loadRequest.noPlaceholder();
//        }
//        if (errorDrawable != null) {
//            loadRequest.error(errorDrawable);
//        }
//        loadRequest.noFade();
//        loadRequest.into(targetIv, callback);
//    }

    /**
     * 本类中图片加载　重载方法的根方法
     * @param context Context
     * @param picUrl 图片url
     * @param newWidth 指定的宽
     * @param newHeight 指定的高
     * @param holderDrawable　占位　Drawable
     * @param errorDrawable　加载失败/错误时的占位　Drawable
     * @param targetIv　加载到的目标　ImageView
     * @param callback　结果监听回调　RequestListener<Drawable>
     * @param isDontAnimate true: 不应用动画;　false:应用动画
     */
    public static void loadImage(Context context, String picUrl, int newWidth, int newHeight, Drawable holderDrawable,
                                 Drawable errorDrawable, ImageView targetIv
            , RequestListener<Drawable> callback, boolean isDontAnimate) {
        RequestBuilder<Drawable> requestBuilder = loadImageRequest(context, picUrl);
        RequestOptions options = new RequestOptions();
        if (newWidth > 0 && newHeight > 0) {
            RequestOptions requestOptions = options.override(newWidth, newHeight).centerCrop();
        }

//    else{
//        //            loadRequest.fit();
//    }

        if (holderDrawable != null) {
            RequestOptions requestOptions = options.placeholder(holderDrawable);
        }

//    else{
////        loadRequest.noPlaceholder();
//    }

        if (errorDrawable != null) {
            RequestOptions requestOptions = options.error(errorDrawable);
        }
        if (isDontAnimate) {
            RequestOptions requestOptions = options.dontAnimate();
        }
        if (callback != null) {
            RequestBuilder<Drawable> builder = requestBuilder.listener(callback);
        }
        requestBuilder.apply(options)
                .into(targetIv);
    }

    private static void throwCannotException(String reason) {
        throw new IllegalArgumentException("no " + reason + ",can't load image pic...");
    }

//    private static RequestCreator loadImageRequest(Context context, String picUrl, File localPicFile,int localPicResId) {
//        if (Util.isEmpty(picUrl) && null == localPicFile && localPicResId <= 0) {
//            throwCannotException("pic path ");
//        }
//        Picasso picasso = Picasso.with(context);
//        if (!Util.isEmpty(picUrl)) {
//            return picasso.load(picUrl);
//        }
//        if (localPicFile != null) {
//            return picasso.load(localPicFile);
//        }
//        return picasso.load(localPicResId);
//    }

    //    public static RequestCreator loadImageRequest(Context context, String picUrlOrPath) {
//        if (Util.isEmpty(picUrlOrPath)) {
//            throwCannotException("picUrl");
//        }
//        return loadImageRequest(context, picUrlOrPath, null, 0);
//    }
//    public static RequestCreator loadImageRequest(Context context, File localPicFile) {
//        if (null == localPicFile) {
//            throwCannotException("pic file");
//        }
//        return loadImageRequest(context, null, localPicFile, 0);
//    }
//    public static RequestCreator loadImageRequest(Context context, int localPicResId) {
//        if (localPicResId <= 0) {
//            throwCannotException("valid local pic res id");
//        }
//        return loadImageRequest(context, null, null, localPicResId);
//    }
    public static void loadImage(Context context, String picUrl, int newWidth, int newHeight, int holderDrawableResId,
                                 int errorDrawableResId, ImageView targetIv
            , RequestListener<Drawable> callback, boolean isDontAnimate) {
        Resources res = context.getResources();
        Drawable holderPic = null;
        if (holderDrawableResId != 0) {
            holderPic = ResourcesCompat.getDrawable(res, holderDrawableResId, null);
        }
        Drawable errorDrawable = null;
        if (errorDrawableResId != 0) {
            errorDrawable = ResourcesCompat.getDrawable(res, errorDrawableResId, null);
        }
        loadImage(context, picUrl, newWidth, newHeight, holderPic,
                errorDrawable,
                targetIv, callback, isDontAnimate);
    }

    public static void loadImage(Context context, String picUrl, int holderDrawableResId,
                                 int errorDrawableResId, ImageView targetIv
            , RequestListener callback, boolean isDontAnimate) {
        loadImage(context, picUrl, 0, 0, holderDrawableResId, errorDrawableResId, targetIv, callback, isDontAnimate);
    }

    public static void loadImage(Context context, String picUrl, int holderDrawableResId,
                                 int errorDrawableResId, ImageView targetIv) {
        loadImage(context, picUrl, holderDrawableResId, errorDrawableResId, targetIv, null, true);
    }

    public static void loadImage(Context context, String picUrl, ImageView targetIv, RequestListener callback) {
        loadImage(context, picUrl, 0, 0, targetIv, callback, true);
    }

    public static void loadImage(Context context, String picUrl, ImageView targetIv) {
        loadImage(context, picUrl, targetIv, null);
    }

    public static void loadResizeImage(Context context, String picUrl, int resizeW, int resizeH, ImageView targetIv) {
        loadImage(context, picUrl, resizeW, resizeH, null, null, targetIv, null, true);
    }

    public static void loadImage(Context context, Object model, ImageView ivTarget) {
        Glide.with(context).load(model)
                .into(ivTarget)
        ;
    }

    public static RequestBuilder<Drawable> loadImageRequest(Context context, Object model) {
        return Glide.with(context).load(model);
    }

    public static RequestBuilder<Bitmap> loadBitmapeRequest(Context context, Object model) {
        return Glide.with(context).asBitmap().load(model);
    }

    public static void loadBitmap(Context context, Object model, Target target) {
        Glide.with(context).asBitmap().load(model).into(target);
    }

    public static void loadGif(Context context, int gifDrawableResId, ImageView ivTarget, int needPlayTime) {
        loadGifModel(context, gifDrawableResId, 0, ivTarget, needPlayTime);
    }

    public static void loadGifModel(Context context, Object mayBeGifModel, @RawRes @DrawableRes int defHolderPicRes, ImageView ivTarget, final int needPlayTime) {
        if (mayBeGifModel == null) {
            return;
        }
        RequestBuilder<GifDrawable> gifDrawableBuilder = null;
        try {
            gifDrawableBuilder = Glide.with(context).asGif()
            ;
        } catch (Exception e) {
            //java.lang.IllegalArgumentException You cannot start a load for a destroyed activity
            gifDrawableBuilder = null;
            e.printStackTrace();
        }
        if (gifDrawableBuilder == null) {
            return;
        }
        if (defHolderPicRes != 0) {
            gifDrawableBuilder.placeholder(defHolderPicRes)
                    .error(defHolderPicRes);
        }
        RequestListener<GifDrawable> loadGifDrawableListener = null;
        if (needPlayTime >= 1) {
            loadGifDrawableListener = new RequestListener<GifDrawable>() {
                @Override
                public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
                    return false;
                }

                @Override
                public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
                    resource.setLoopCount(needPlayTime);
                    return false;
                }
            };
            gifDrawableBuilder.listener(loadGifDrawableListener);
        }
        if (mayBeGifModel instanceof Integer) {//还有:load(Bitmap xx);load(byte[]xxx);loadDrawable(Drawable xx);有差异
            Integer gifResId = (Integer) mayBeGifModel;
            if (gifResId != 0) {
                gifDrawableBuilder.load(gifResId);
            } else {
                return;
            }
        } else {
            gifDrawableBuilder.load(mayBeGifModel);
        }
        gifDrawableBuilder.into(ivTarget);
    }

    public static <AsX> void loadImageIntoTarget(Context context, String imageDataUrl, int defPicRes, Class<AsX> resourseClassType, Target<AsX> target) {
        Glide.with(context)
                .as(resourseClassType)
                .load(imageDataUrl)
                .error(defPicRes)
                .placeholder(defPicRes)
                .into(target)
        ;
    }

    public static ColorDrawable createDefHolderColorDrawable(int theColor) {
        if (theColor == 0) {//透明
            theColor = Color.parseColor("#555555");
        }
        return new ColorDrawable(theColor);
    }

    public static void loadImageOrGif(Context context, String imgUrl, @DrawableRes @RawRes int defPicRes, ImageView imageView, int gifPlayTimes) {
        if (TextUtils.isEmpty(imgUrl)) {
            if (imageView != null) {
                imageView.setImageResource(defPicRes);
            }
            return;
        }
        if (imgUrl.endsWith(".gif")) {
            loadGifModel(context, imgUrl, defPicRes, imageView, gifPlayTimes);
        } else {
            loadImage(context, imgUrl, defPicRes, defPicRes, imageView);
        }
    }
    //and so on 还可以重载出很多加载的方法


    /**
     * 将图片放大或缩小到指定尺寸
     */
    public static Bitmap resizeImage(Bitmap source, int w, int h) {
        int width = source.getWidth();
        int height = source.getHeight();
        float scaleWidth = ((float) w) / width;
        float scaleHeight = ((float) h) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        return Bitmap.createBitmap(source, 0, 0, width, height, matrix, true);
    }

    /**
     * 将图片剪裁为圆形
     */
    public static Bitmap createCircleImage(Bitmap source) {
        int length = Math.min(source.getWidth(), source.getHeight());
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        Bitmap target = Bitmap.createBitmap(length, length, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(target);
        canvas.drawCircle(length / 2, length / 2, length / 2, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(source, 0, 0, paint);
        return target;
    }

//    /**
//     * 使用Glide来下载【图片】文件
//     * 注意：非异步下载
//     * @param context Context
//     * @param fileUrl 要下载的文件地址
//     * @param targetLocalFilePath 目标存储
//     * @return file
//     */
//    private static File download(Context context, String fileUrl,String targetLocalFilePath) {
//        if (fileUrl == null || "".equals(fileUrl.trim())) {
//            return null;
//        }
//        File targetFile = null;
//        try {
//            targetFile = Glide.with(context).download(fileUrl).submit().get();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        if (targetLocalFilePath != null && !"".equals(targetLocalFilePath.trim())) {//表示需要复制到目标路径
//             //判断是否需要复制到目标
//            boolean isValidFile = targetFile != null && targetFile.length() > 1;
//            if (isValidFile) {
//                String downloadFileAbsPath = targetFile.getAbsolutePath();
//                CommonLog.e("info", "--->download() downloadFileAbsPath=" + downloadFileAbsPath);
//                if (!targetLocalFilePath.equals(downloadFileAbsPath)) {//一般不会相同
//                    File targetLocalFile = new File(targetLocalFilePath);
//                    boolean needCopyToTargetPath = true;
//
//                    boolean copySuc = copyFile(targetFile, targetLocalFile);
//                    if (copySuc) {
//                        targetFile.delete();
//                        targetFile = targetLocalFile;
//                    }
//                }
//            }
//        }
//        return targetFile;
//    }

    public static boolean copyFile(File srcFile, File targetFile) {
        if (srcFile == null || srcFile.length() < 1 || targetFile == null) {
            return false;
        }
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(targetFile, true);
            byte[] readBuf = new byte[1024];
            int hasReadLen = -1;
            while ((hasReadLen = fis.read(readBuf)) != -1) {
                byte[] readDatas = new byte[hasReadLen];
                System.arraycopy(readBuf, 0, readDatas, 0, hasReadLen);
                fos.write(readDatas);
            }
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    @WorkerThread
    public static File downloadAndCopyToTarget(Context context, String fileUrl, String targetDirPath, String targetFileName, boolean deleteSrcFile) {
        File downloadResultFile = download(context, fileUrl);
        if (downloadResultFile == null) {
            return null;
        }
        boolean isTargetDirNull = isTextEmpty(targetDirPath);
        boolean isTargetFileNameNull = isTextEmpty(targetFileName);
        if (!isTargetDirNull) {//表示需要复制到目标路径
            boolean isDownloadFileValid = downloadResultFile.length() > 1;
            if (isDownloadFileValid) {//下载的文件有效
                String downloadedFileName = downloadResultFile.getName();
                AppLog.e("info", "-->downloadAndCopyToTarget() downloadedFileName = " + downloadedFileName);
                String targetWholeFilePath = appendSeparator(targetDirPath);
                File targetFile = null;
                if (isTargetFileNameNull) {//指定的需要复制的文件名为空,则使用下载好了的文件的文件名
                    targetWholeFilePath += downloadedFileName;
                    targetFile = new File(targetWholeFilePath);
                    if (targetFile.exists() && targetFile.length() > 1) {
                        //这种情况下已经存在了，则不用复制了,直接返回
                        AppLog.e("info", "-->downloadAndCopyToTarget() not need copy file...");
                        return targetFile;
                    }
                } else {
                    targetWholeFilePath += targetFileName;
                }
                targetFile = new File(targetWholeFilePath);
                boolean isCopySuc = copyFile(downloadResultFile, targetFile);
                if (isCopySuc) {
                    if (deleteSrcFile) {
                        downloadResultFile.delete();
                    }
                    downloadResultFile = targetFile;
                }
            }
        }
        return downloadResultFile;
    }

    /**
     * 下载图片文件
     *
     * @param context Context
     * @param fileUrl 图片文件Url
     * @return File
     */
    @WorkerThread
    public static File download(Context context, String fileUrl) {
        if (fileUrl == null || "".equals(fileUrl.trim())) {
            return null;
        }
        File targetFile = null;
        try {
            targetFile = Glide.with(context).download(fileUrl).submit().get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return targetFile;
    }

    private static boolean isTextEmpty(String text) {
        if (text == null || text.trim().length() == 0) {
            return true;
        }
        return false;
    }

    private static String appendSeparator(String text) {
        if (!isTextEmpty(text)) {
            if (!text.endsWith("/")) {
                return text + "/";
            }
        }
        return text;
    }
}
